package com.nt.train.utils;

import com.google.common.collect.Range;
import com.google.common.collect.RangeMap;
import com.google.common.collect.TreeRangeMap;
import groovy.lang.IntRange;
//import groovy.lang.IntRange;

import java.util.*;

/**
 * @author hlf
 * @version 1.0
 * @date 2022/9/15 11:26
 */
public class LGauva {

    /**
     * 责任链模式
     */
    public interface MsgProcesser {
        boolean match(int msg);
        String processor(int msg);
    }

    public static class Processor implements MsgProcesser{
        @Override
        public boolean match(int msg) {
            return msg < 10000;
        }

        @Override
        public String processor(int msg) {
            return String.valueOf(msg);
        }
    }

    public static class WProcessor implements MsgProcesser{
        @Override
        public boolean match(int msg) {
            return msg < 10000 * 100;
        }

        @Override
        public String processor(int msg) {
            return msg / 10000 + "万+";
        }
    }

    public static class ProcessChain {
        int index = 0;
        List<MsgProcesser> processers = new ArrayList<>();

        public ProcessChain add(MsgProcesser p) {
            processers.add(p);
            return this;
        }

        public String process(int msg) {
            if(index == processers.size()) {
                return "";
            }
            MsgProcesser proccess = processers.get(index);
            if (proccess.match(msg)) {
                return proccess.processor(msg);
            }
            index++;
            return process(msg);
        }

    }

    /**
     * 策略模式 1
     */
    public interface Strategy {
        String processor(int msg);
    }
    private static Map<IntRange, Strategy> rangeStrategyMap = new HashMap<>();
    static {
        rangeStrategyMap.put(new IntRange(0, 9999), String::valueOf);
        rangeStrategyMap.put(new IntRange(10000, 10000 * 100 - 1), msg -> msg / 10000 + "万+");
        rangeStrategyMap.put(new IntRange(10000 * 100, 10000 * 1000 - 1), msg -> msg / 10000 / 100 + "百万+");
        rangeStrategyMap.put(new IntRange(10000 * 1000, Integer.MAX_VALUE), msg -> msg / 10000 / 1000 + "千万+");
    }
    public static Map<IntRange, Strategy> getRangeStrategyMap() {
        return rangeStrategyMap;
    }

    /**
     * 策略模式 2
     */
    private static RangeMap<Integer, Strategy> rangeMap = TreeRangeMap.create();
    static {
        rangeMap.put(Range.closedOpen(0, 10000), String::valueOf);
        rangeMap.put(Range.closedOpen(10000, 10000 * 100), msg -> msg / 10000 + "万+");
        rangeMap.put(Range.closedOpen(10000 * 100, 10000 * 1000), msg -> msg / 10000 / 100 + "百万+");
        rangeMap.put(Range.closedOpen(10000 * 1000, Integer.MAX_VALUE), msg -> msg / 10000 / 1000 + "千万+");
    }
    public static RangeMap<Integer, Strategy> getRangeMap() {
        return rangeMap;
    }

    public String transferNumber(int number) {
        int base = 10000; // 1万
        if (number <= base) {
            return String.valueOf(number);
        } else if (number < base * 100) {
            return String.valueOf(number / base) + "万+";
        } else if (number < base * 1000) {
            return String.valueOf(number / base / 100) + "百万+";
        } else {
            return String.valueOf(number / base / 1000) + "千万+";
        }
    }

    // Monday（星期一）、Tuesday（星期二）、Wednesday（星期三）、
    // Thursday（星期四）、Friday（星期五）、Saturday（星期六）、Sunday（星期日）。
    public String transferWeek(int day) {
        switch (day) {
            case 0:
                return "Sunday";
            case 1:
                return "Monday";
            case 2:
                return "Tuesday";
            case 3:
                return "Wednesday";
            case 4:
                return "Thursday";
            case 5:
                return "Friday";
            case 6:
                return "Saturday";
            default:
                return "";
        }
    }

    public enum Week {
        DEFAULT(-1) {
            @Override
            public String getWeekDay() {
                return "";
            }
        },
        SUN(0) {
            @Override
            public String getWeekDay() {
                return "Sunday";
            }
        },
        Mon(1) {
            @Override
            public String getWeekDay() {
                return "Sunday";
            }
        },
        TUE(2) {
            @Override
            public String getWeekDay() {
                return "Tuesday";
            }
        },
        WED(3) {
            @Override
            public String getWeekDay() {
                return "Wednesday";
            }
        },
        THU(4) {
            @Override
            public String getWeekDay() {
                return "Thursday";
            }
        },
        FRI(5) {
            @Override
            public String getWeekDay() {
                return "Friday";
            }
        },
        SAT(6) {
            @Override
            public String getWeekDay() {
                return "Saturday";
            }
        },
        ;
        private final int day;

        public static Week valueOf(int day) {
            for(Week week : Week.values()) {
                if (!week.equals(Week.DEFAULT) && week.getDay() == day) {
                    return week;
                }
            }
            return Week.DEFAULT;
        }

        public int getDay() {
            return day;
        }

        public abstract String getWeekDay();

        Week(int day) {
            this.day = day;
        }
    }

//    public static void main(String[] args) {
//        LGauva lGauva = new LGauva();
//        // 原始方法
//        System.out.println(lGauva.transferNumber(2));
//        System.out.println(lGauva.transferNumber(2000));
//        System.out.println(lGauva.transferNumber(20000));
//        System.out.println(lGauva.transferNumber(20000 * 100));
//        System.out.println(lGauva.transferNumber(20000 * 1000));
//        System.out.println(lGauva.transferNumber(20000 * 10000));
//
//        // 责任链
//        ProcessChain chain = new ProcessChain();
//        chain.add(new Processor());
//        chain.add(new WProcessor());
//        System.out.println(chain.process(20000));
//
//
//        int num = 20000 * 201;
//        // 策略1
//        Map<IntRange, Strategy> rangeStrategyMap = LGauva.getRangeStrategyMap();
//        Optional<Strategy> first = rangeStrategyMap.entrySet().stream()
//                .filter(entry -> entry.getKey().contains(num))
//                .map(Map.Entry::getValue)
//                .findFirst();
//        String processor = first.orElse(String::valueOf).processor(num);
//        System.out.println(processor);
//
//        // 策略2
//        RangeMap<Integer, Strategy> rangeMap = LGauva.getRangeMap();
//        Strategy strategy = rangeMap.get(num);
//        if (strategy == null) {
//            strategy = String::valueOf;
//        }
//        System.out.println(strategy.processor(num));
//
//        // 使用模版模式【枚举类】
//        System.out.println(lGauva.transferWeek(0));
//        System.out.println(lGauva.transferWeek(6));
//        System.out.println(LGauva.Week.valueOf(0).getWeekDay());
//        System.out.println(LGauva.Week.valueOf(6).getWeekDay());
//    }
}
